package cn.etynit.service.impl;

import cn.etynit.domain.MovieTicket;
import cn.etynit.domain.User;
import cn.etynit.domain.UserMovie;
import cn.etynit.exception.GlobalException;
import cn.etynit.exception.GlobalExceptionCodeEnum;
import cn.etynit.feign.MovieService;
import cn.etynit.feign.UserMovieService;
import cn.etynit.mapper.UserMapper;
import cn.etynit.result.JsonResult;
import cn.etynit.service.IUserService;
import cn.etynit.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author etyn
 * @since 2022-11-24
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private MovieService movieService;
    
    @Autowired
    private UserMovieService userMovieService;

    /**
     * 电影票查询
     * @return
     */
    @Override
    public JsonResult getMovie() {
        return movieService.list();
    }

    /**
     * 电影票购买
     * @param movieId
     * @param count
     * @return
     */
    @Override
    public JsonResult byMovie(Long movieId, Long count) {
        JsonResult jsonResult = movieService.get(movieId);
        // 根据电影票id查询电影，返回的信息如果不是成功的就返回异常信息
        if (!jsonResult.isSuccess()){
            return jsonResult;
        }
        // 根据电影票id查询电影，返回的信息中data数据如果是空，证明没有该电影
        Object obj = jsonResult.getData();
        if (obj == null){
            throw new GlobalException("电影不存在！");
        }
        // 从返回的数据中获取到电影票对象
        MovieTicket movieTicket = JSONObject.parseObject(JSONObject.toJSONString(obj), MovieTicket.class);
        // 查询剩余电影票，如果时空的或者小于购买的电影票数，抛异常
        Long stock = movieTicket.getStock();
        if (stock == null || stock < count){
            throw new GlobalException("电影票库存不足！");
        }
        // 获取一个写死的user对象
        User user = selectById(1L);
        // 购买电影票数*电影票价
        BigDecimal multiply = movieTicket.getPrice().multiply(new BigDecimal(count));
        // 如果用户的余额比购买的电影票金额小，抛异常   // compareTo是BigDecimal比较大小的方式，前者比后者小是-1，大是1
        if (user.getBalance().compareTo(multiply) < 0){
            throw new GlobalException("金额不足！");
        }
        // 如果电影结束时间小于当前时间，抛异常
        if (!new Date().before(movieTicket.getEndTime())){
            throw new GlobalException("已过观看时间！");
        }
        // 买电影
        JsonResult by2JsonResult = movieService.byMovie(movieId, count);
        if (!by2JsonResult.isSuccess()){
            return by2JsonResult;
        }
        user.setBalance(user.getBalance().subtract(multiply));
        updateById(user);
        return JsonResult.success("购买成功！");
    }

    /**
     * 新增用户送电影票
     * @param user
     * @return
     */
    @Override
    public JsonResult activity(User user) {
        // 查询所有电影,没有查到就返回异常
        JsonResult list = movieService.list();
        if (!list.isSuccess()){
            return list;
        }
        // 查到了就转化为电影集合
        List<MovieTicket> movieTickets = JSONObject.parseArray(JSONObject.toJSONString(list.getData()), MovieTicket.class);
        // 创建随机对象random
        Random random = new Random();
        // 库存校验，电影集合中的对象里面的库存数必须大于等于1
        List<MovieTicket> collect = movieTickets.stream().filter(movieTicket -> movieTicket.getStock() >= 1).collect(Collectors.toList());
        // 集合对象collect的get方法获取其中一个对象（random的nextInt获取随机数，从collect集合中的长度里面选取）
        MovieTicket movieTicket = collect.get(random.nextInt(collect.size()));
        // 如果没有就抛异常
        AssertUtil.isNotNull(movieTicket, GlobalExceptionCodeEnum.ERROR);
        insert(user);
        // 赠送电影票
        JsonResult jsonResult = movieService.giving(movieTicket.getId(), 1L, user.getId());
        AssertUtil.isTrue(jsonResult.isSuccess(),GlobalExceptionCodeEnum.ERROR);
        return JsonResult.success();
    }

    /**
     * 看电影
     * @param movieId
     * @param count
     * @return
     */
    @Override
    public JsonResult watch(Long movieId, Long count) {
        // 根据movieId找到对象电影对象，没找到就返回异常
        JsonResult jsonResult = movieService.get(movieId);
        if (!jsonResult.isSuccess()){
            return jsonResult;
        }
        // 获取返回的电影票，不存在就抛异常
        Object obj = jsonResult.getData();
        if (obj == null){
            throw new GlobalException("电影不存在！");
        }
        // 获取到电影票对象
        MovieTicket movieTicket = JSONObject.parseObject(JSONObject.toJSONString(obj), MovieTicket.class);
        // 查看用户电影票，没找到就返回异常信息
        JsonResult userStock = userMovieService.getUserStock(1L, movieId);
        if (!userStock.isSuccess()){
            return userStock;
        }
        UserMovie userMovie = JSONObject.parseObject(JSONObject.toJSONString(userStock.getData()), UserMovie.class);
        if (userMovie.getCount() < count){
            throw new GlobalException("没有电影票可观看");
        }

        if(!new Date().before(movieTicket.getEndTime())){
            throw new GlobalException("已过观影时间！");
        }
        // 扣减库存
        userMovie.setCount(userMovie.getCount() - count);
        userMovieService.saveOrUpdate(userMovie);
        return JsonResult.success("欢迎来看电影！");
    }
}
